package com.zzedu.integration.oss.tencent.impl;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.*;
import com.zzedu.integration.oss.IOssClientService;
import com.zzedu.integration.oss.dto.FileInfoDTO;
import com.zzedu.integration.oss.dto.OssFileResult;
import com.zzedu.integration.oss.tencent.config.TencentProp;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * oss 上传
 *
 * @author Administrator
 */
@Component
public class TencentClientServiceImpl implements IOssClientService {
    private static final Logger log = LoggerFactory.getLogger(TencentClientServiceImpl.class);
    @Autowired
    private COSClient cosClient;
    @Autowired
    private TencentProp tencentProp;


    /**
     * 创建bucket
     *
     * @param bucketName bucket名称
     */
    private void createBucket(String bucketName) throws Exception {
        if (!cosClient.doesBucketExist(bucketName)) {
            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
            createBucketRequest.setCannedAcl(CannedAccessControlList.Private);
            cosClient.createBucket(createBucketRequest);
        }
    }

    /**
     * 根据bucketName删除信息
     *
     * @param bucketName bucket名称
     */
    public void removeBucket(String bucketName) throws Exception {
        //cosClient.deleteBucket(bucketName);
    }


    @Override
    public OssFileResult removeObject(String bucketName, String objectName) {
        OssFileResult ossFileResult = new OssFileResult();
        // cosClient.deleteObject(bucketName, objectName);
        ossFileResult.setSuccess(true);
        return ossFileResult;
    }

    /**
     * 上传文件
     *
     * @param file 文件
     * @return
     */
    public OssFileResult<FileInfoDTO> uploadFile(String dir, String allPathFileName, String reFileName) {
        InputStream inputStream = null;
        try {
            // 判断存储桶是否存在
            createBucket(tencentProp.getBucketName());
            File file = new File(allPathFileName);
            inputStream = new FileInputStream(file);
            String oldName = file.getName();
            String suffix = oldName.substring(oldName.lastIndexOf(".") + 1);
            // 生成唯一文件名，当前时间 + 随机UUID + 文件类型
            String fileName = (org.apache.commons.lang3.StringUtils.isNotBlank(dir) ? dir + "/" : "") + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + "-" + reFileName + "." + suffix;
            // 上传文件到cos
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(inputStream.available());
            PutObjectRequest putObjectRequest = new PutObjectRequest(tencentProp.getBucketName(), fileName, inputStream, metadata);
            cosClient.putObject(putObjectRequest);

            inputStream.close();
            // 返回文件在cos上的访问url
            FileInfoDTO fileInfoDTO = new FileInfoDTO();
            fileInfoDTO.setFileSuffix(suffix);
            fileInfoDTO.setSize(metadata.getContentLength());
            fileInfoDTO.setShowUrl(convertURL(fileName));
            fileInfoDTO.setUrl(fileName);
            fileInfoDTO.setNewFileName(fileName);
            fileInfoDTO.setOriginalFilename(oldName);
            return new OssFileResult<FileInfoDTO>() {{
                setSuccess(true);
                setData(fileInfoDTO);
            }};
        } catch (Exception e) {
            log.error("上传文件失败,详细{}", e.getMessage());
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
        return new OssFileResult() {{
            setSuccess(false);
            setMsg("上传文件失败");
        }};
    }

    /**
     * 上传文件
     *
     * @param file 文件
     * @return
     */
    public OssFileResult<FileInfoDTO> uploadFile(byte[] data, String dir, String orgName, String reFileName) {
        InputStream inputStream = null;
        try {
            // 判断存储桶是否存在
            createBucket(tencentProp.getBucketName());

            String oldName = orgName;
            String suffix = oldName.substring(oldName.lastIndexOf(".") + 1);
            // 生成唯一文件名，当前时间 + 随机UUID + 文件类型
            String fName = UUID.randomUUID().toString();
            if (org.apache.commons.lang3.StringUtils.isNotBlank(reFileName)) {
                fName = reFileName;
            }
            String fileName = (org.apache.commons.lang3.StringUtils.isNotBlank(dir) ? dir + "/" : "") + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + "/" + fName + "." + suffix;
            // 上传文件到cos
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(data.length);
            inputStream = new ByteArrayInputStream(data);
            PutObjectRequest putObjectRequest = new PutObjectRequest(tencentProp.getBucketName(), fileName, inputStream, metadata);
            cosClient.putObject(putObjectRequest);
            inputStream.close();
            // 返回文件在cos上的访问url
            FileInfoDTO fileInfoDTO = new FileInfoDTO();
            fileInfoDTO.setFileSuffix(suffix);
            fileInfoDTO.setSize((long)data.length);
            fileInfoDTO.setShowUrl(convertURL(fileName));
            fileInfoDTO.setUrl(fileName);
            fileInfoDTO.setNewFileName(fileName);
            fileInfoDTO.setOriginalFilename(oldName);
            return new OssFileResult<FileInfoDTO>() {{
                setSuccess(true);
                setData(fileInfoDTO);
            }};
        } catch (Exception e) {
            log.error("上传文件失败,详细{}", e.getMessage());
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
        return new OssFileResult() {{
            setSuccess(false);
            setMsg("上传文件失败");
        }};
    }

    @Override
    public OssFileResult<FileInfoDTO> uploadFile(String dir, String allPathFileName) {
        return uploadFile(dir, allPathFileName, UUID.randomUUID().toString());
    }

    @Override
    public String convertURL(String objectName) {
        return convertURL(objectName, 12 * 60 * 60L * 1000L);
    }

    @Override
    public String convertURL(String domain, String objectName) {
        if (!org.apache.commons.lang3.StringUtils.isNotBlank(objectName)) {
            return "";
        }
        try {
            if (StringUtils.isNotBlank(domain)) {
                return domain + objectName;
            }
            return tencentProp.getOssUrl() + objectName;
        } catch (Exception e) {
            log.error("图片转换出错,详细:" + e.getMessage());
            return "";
        }
    }

    @Override
    public String convertURL(String objectName, long expire) {
        if (!org.apache.commons.lang3.StringUtils.isNotBlank(objectName)) {
            return "";
        }
        try {
            return tencentProp.getOssUrl() + objectName;
        } catch (Exception e) {
            log.error("图片转换出错,详细:" + e.getMessage());
            return "";
        }
    }

    @Override
    public OssFileResult removeObject(String objectName) {
        OssFileResult ossFileResult = new OssFileResult();
        //    cosClient.deleteObject(tencentProp.getBucketName(), objectName);
        ossFileResult.setSuccess(true);
        return ossFileResult;
    }


    @Override
    public OssFileResult deleteObject(String objectName) {
        OssFileResult ossFileResult = new OssFileResult();
        cosClient.deleteObject(tencentProp.getBucketName(), objectName);
        ossFileResult.setSuccess(true);
        return ossFileResult;
    }

    /**
     * 下载对象
     *
     * @param objectName
     * @return
     */
    public byte[] download(String objectName) {
        COSObjectInputStream cosObjectInput = null;
        try {
            COSObject cosObject = cosClient.getObject(new GetObjectRequest(tencentProp.getBucketName(), objectName));
            cosObjectInput = cosObject.getObjectContent();
            return IOUtils.toByteArray(cosObjectInput);
        } catch (Exception e) {
            log.error("下载{}文件到本地失败,详细:{}", objectName, e.getMessage());
        } finally {
            IOUtils.closeQuietly(cosObjectInput);
        }
        return null;
    }

    @Override
    public boolean doesObjectExist(String objectName) {
        return cosClient.doesObjectExist(tencentProp.getBucketName(), objectName);
    }

    @Override
    public String ossDomain() {
        return tencentProp.getOssUrl();
    }
}
